package com.ruoyi.function.service.impl;


import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.function.domain.ServiceArea;
import com.ruoyi.function.domain.vo.ServiceAreaVO;
import com.ruoyi.function.mapper.ServiceAreaMapper;
import com.ruoyi.function.service.IServiceAreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class ServiceAreaServiceImpl implements IServiceAreaService {
    
    @Autowired
    private ServiceAreaMapper serviceAreaMapper;
    
    @Autowired
    private RedisCache redisCache;
    
    private static final String AREA_CACHE_KEY = "service_area:";
    private static final String AREA_TREE_CACHE_KEY = "service_area:tree";
    private static final Integer CACHE_TIMEOUT = 24; // 缓存24小时
    
    @Override
    public ServiceArea getAreaByCode(String areaCode) {
        // 先从缓存获取
        String cacheKey = AREA_CACHE_KEY + "code:" + areaCode;
        ServiceArea area = redisCache.getCacheObject(cacheKey);
        if (area != null) {
            return area;
        }
        
        // 缓存没有，从数据库查询
        area = serviceAreaMapper.selectByCode(areaCode);
        if (area != null) {
            // 放入缓存
            redisCache.setCacheObject(cacheKey, area, CACHE_TIMEOUT, TimeUnit.HOURS);
        }
        return area;
    }
    
    @Override
    public List<ServiceArea> getAreasByCodes(List<String> areaCodes) {
        if (areaCodes == null || areaCodes.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<ServiceArea> result = new ArrayList<>();
        for (String areaCode : areaCodes) {
            ServiceArea area = getAreaByCode(areaCode);
            if (area != null) {
                result.add(area);
            }
        }
        return result;
    }
    
    @Override
    public String getAreaFullPathName(String areaCode) {
        ServiceArea area = getAreaByCode(areaCode);
        if (area == null) {
            return null;
        }
        
        List<String> pathNames = new ArrayList<>();
        pathNames.add(area.getNodeName());
        
        // 向上查找父级
        String parentCode = area.getCodeParent();
        while (parentCode != null && !parentCode.equals("0")) {
            ServiceArea parentArea = serviceAreaMapper.selectByCode(parentCode);
            if (parentArea == null) {
                break;
            }
            pathNames.add(0, parentArea.getNodeName());
            parentCode = parentArea.getCodeParent();
        }
        
        return String.join("/", pathNames);
    }
    
    @Override
    public Map<String, String> getAreaFullPathNames(List<String> areaCodes) {
        if (areaCodes == null || areaCodes.isEmpty()) {
            return new HashMap<>();
        }
        
        Map<String, String> result = new HashMap<>();
        for (String areaCode : areaCodes) {
            String fullPathName = getAreaFullPathName(areaCode);
            if (fullPathName != null) {
                result.put(areaCode, fullPathName);
            }
        }
        return result;
    }
    
    @Override
    public List<ServiceAreaVO> getAreaTree() {
        // 先从缓存获取
        List<ServiceAreaVO> cacheTree = redisCache.getCacheObject(AREA_TREE_CACHE_KEY);
        if (cacheTree != null) {
            return cacheTree;
        }
        
        // 一次性查出所有数据，传入 null 表示查询所有层级
        List<ServiceArea> allAreas = serviceAreaMapper.selectList(null);
        
        // 构建父子关系map
        Map<String, List<ServiceArea>> parentChildrenMap = allAreas.stream()
                .collect(Collectors.groupingBy(ServiceArea::getCodeParent));
        
        // 获取顶级节点(省份)
        List<ServiceArea> provinces = parentChildrenMap.get("0");
        if (provinces == null) {
            return new ArrayList<>();
        }
        
        // 构建树结构
        List<ServiceAreaVO> tree = provinces.stream()
                .map(province -> convertToTreeNode(province, parentChildrenMap))
                .collect(Collectors.toList());
        
        // 放入缓存
        redisCache.setCacheObject(AREA_TREE_CACHE_KEY, tree, CACHE_TIMEOUT, TimeUnit.HOURS);
        
        return tree;
    }
    
    private ServiceAreaVO convertToTreeNode(ServiceArea area, Map<String, List<ServiceArea>> parentChildrenMap) {
        ServiceAreaVO node = convertToVO(area);
        
        // 获取子节点
        List<ServiceArea> children = parentChildrenMap.get(area.getNodeCode());
        if (children != null && !children.isEmpty()) {
            node.setChildren(children.stream()
                    .map(child -> convertToTreeNode(child, parentChildrenMap))
                    .collect(Collectors.toList()));
        }
        
        return node;
    }
    
    @Override
    public List<ServiceAreaVO> getAreasByLevel(Integer level) {
        // 先从缓存获取
        String cacheKey = AREA_CACHE_KEY + "level:" + level;
        List<ServiceAreaVO> cacheList = redisCache.getCacheObject(cacheKey);
        if (cacheList != null) {
            return cacheList;
        }
        
        // 从数据库查询
        List<ServiceArea> areas = serviceAreaMapper.selectByLevel(level);
        List<ServiceAreaVO> result = areas.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 放入缓存
        redisCache.setCacheObject(cacheKey, result, CACHE_TIMEOUT, TimeUnit.HOURS);
        
        return result;
    }
    
    @Override
    public List<ServiceAreaVO> getChildrenByParentCode(String parentCode) {
        // 先从缓存获取
        String cacheKey = AREA_CACHE_KEY + "parent:" + parentCode;
        List<ServiceAreaVO> cacheList = redisCache.getCacheObject(cacheKey);
        if (cacheList != null) {
            return cacheList;
        }
        
        // 从数据库查询
        List<ServiceArea> children = serviceAreaMapper.selectByParentCode(parentCode);
        List<ServiceAreaVO> result = children.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 放入缓存
        redisCache.setCacheObject(cacheKey, result, CACHE_TIMEOUT, TimeUnit.HOURS);
        
        return result;
    }
    
    private ServiceAreaVO convertToVO(ServiceArea area) {
        ServiceAreaVO vo = new ServiceAreaVO();
        vo.setAreaId(area.getNodeCode());
        vo.setAreaName(area.getNodeName());
        vo.setAreaCode(area.getNodeCode());
        vo.setParentId(area.getCodeParent());
        vo.setLevel(area.getNodeLevel());
        vo.setLongitude(area.getLng());
        vo.setLatitude(area.getLat());
        return vo;
    }
    
    @Override
    public List<ServiceArea> getChildrenByParentId(Long parentId) {
        return serviceAreaMapper.selectByParentId(parentId);
    }
} 